﻿using System;
using System.Windows.Forms;
using AFS.VisitationRequestTool.Addin.Common;
using Microsoft.Office.Interop.Outlook;
using Outlook = Microsoft.Office.Interop.Outlook;
using AFS.VisitationRequestTool.Addin.Entities;
using AFS.VisitationRequestTool.Addin.Components;
using System.Runtime.InteropServices;
using AFS.VisitationRequestTool.Addin.Variables;
using AFS.VisitationRequestTool.Addin.Dictionary;
using System.Collections.Generic;

namespace AFS.VisitationRequestTool.Addin.Wrappers
{

    /// <summary>
    /// We derive a Wrapper for each MessageClass / ItemType
    /// </summary>
    public class AppointmentItemWrapper : InspectorWrapper
    {
        /// <summary>
        /// Gets the Object instance behind the Inspector (CurrentItem)
        /// </summary>
        public Outlook.AppointmentItem appointmentItem { get; private set; }

        /// <summary>
        /// .ctor
        /// </summary>
        /// <param name="inspector">The Outlook Inspector instance that should be handled</param>
        public AppointmentItemWrapper(Outlook.Inspector inspector)
            : base(inspector)
        {
            Logger.Verbose("Constructed");
        }

        /// <summary>
        /// Method is called when the Wrapper has been initialized
        /// </summary>
        protected override void Initialize()
        {
            // Get the Item of the current Inspector
            appointmentItem = (Outlook.AppointmentItem)Inspector.CurrentItem;

            // Register for the Item events
            appointmentItem.BeforeRead += new Outlook.ItemEvents_10_BeforeReadEventHandler(Item_BeforeRead);

            appointmentItem.Open += new Outlook.ItemEvents_10_OpenEventHandler(Item_Open);
            appointmentItem.Write += new Outlook.ItemEvents_10_WriteEventHandler(Item_Write);
            appointmentItem.AfterWrite += new Outlook.ItemEvents_10_AfterWriteEventHandler(Item_AfterWrite);

            appointmentItem.Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
            appointmentItem.Application.ItemLoad += new ApplicationEvents_11_ItemLoadEventHandler(Application_ItemLoad);

            Logger.Verbose("Entered");
        }

        void Application_ItemLoad(object Item)
        {
            Logger.Verbose("Entered");
        }

        /// <summary>
        /// Method gets called when the Inspector is activated
        /// </summary>
        protected override void Activate()
        {
            Logger.Verbose("Entered");
        }

        /// <summary>
        /// This Method is called when the Item is visible and the UI is initialized.
        /// </summary>
        /// <param name="Cancel">When you set this property to true, the Inspector is closed.</param>
        void Item_Open(ref bool Cancel)
        {
            Logger.Verbose(String.Format("Entered. Cancel-->{0}", Cancel.ToString()));
        }

        void Application_ItemSend(object Item, ref bool Cancel)
        {
            Cancel = VrPresenter.CancelInvite(appointmentItem);

            if (!Cancel)
            {
                VrPresenter.SaveItemDetails();

                MeetingItem meetingItem = (MeetingItem)Item;

                for (int i = 1; i <= meetingItem.UserProperties.Count; i++)
                {
                    meetingItem.UserProperties[i].Value = appointmentItem.UserProperties[i].Value;
                }
            }

            //Logger.Info("MeetingItem user item properties on Application Item Send");

            //foreach (UserProperty item in ((MeetingItem)Item).UserProperties)
            //{
            //    Logger.Info("\t{0}: {1}", item.Name, item.Value);

            //    ((MeetingItem)Item).UserProperties[item.N
            //}
           

            //Logger.Info("Associated AppointmentItem user item properties on Application Item Send");

            //foreach (UserProperty item in ((MeetingItem)Item).GetAssociatedAppointment(false).UserProperties)
            //{
            //    Logger.Info("\t{0}: {1}", item.Name, item.Value);
            //}

            Logger.Verbose(String.Format("Entered. Cancel-->{0}", Cancel.ToString()));
        }      

        void Item_BeforeRead()
        {
            Logger.Verbose("Entered");
        }

        void Item_AfterWrite()
        {
            //Logger.Info("User item properties after write");

            //foreach (UserProperty item in appointmentItem.UserProperties)
            //{
            //    Logger.Info("\t{0}: {1}", item.Name, item.Value);
            //}
        }

        /// <summary>
        /// This Method is called when the Item is saved.
        /// </summary>
        /// <param name="Cancel">When set to true, the save operation is cancelled</param>
        ///
        void Item_Write(ref bool Cancel)
        {
            //Logger.Info("User item properties before save");

            //foreach (UserProperty item in appointmentItem.UserProperties)
            //{
            //    Logger.Info("\t{0}: {1}", item.Name, item.Value);
            //}

            VrPresenter.SaveItemDetails();

            //Logger.Info("User item properties after save");

            //foreach (UserProperty item in appointmentItem.UserProperties)
            //{
            //    Logger.Info("\t{0}: {1}", item.Name, item.Value);
            //}

            //Logger.Verbose(String.Format("Entered. Cancel-->{0}", Cancel.ToString()));
        }

        /// <summary>
        /// The Close Method is called when the Inspector has been closed.
        /// Do your cleanup tasks here.
        /// The UI is gone, can't access it here.
        /// </summary>
        protected override void Close()
        {
            //Logger.Info("User item properties at close");

            //foreach (UserProperty item in appointmentItem.UserProperties)
            //{
            //    Logger.Info("\t{0}: {1}", item.Name, item.Value);
            //}

            // unregister events
            appointmentItem.Write -= new Outlook.ItemEvents_10_WriteEventHandler(Item_Write);
            appointmentItem.Open -= new Outlook.ItemEvents_10_OpenEventHandler(Item_Open);

            // Release references to COM objects
            appointmentItem = null;

            // required, just stting to NULL may keep a reference in memory of the Garbage Collector.
            GC.Collect();
            GC.WaitForPendingFinalizers();

            Logger.Verbose("Entered");
        }
    }
}

